{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to make callbacks run in the background\n",
    "\n",
    ":::info Prerequisites\n",
    "\n",
    "This guide assumes familiarity with the following concepts:\n",
    "\n",
    "- [Callbacks](/docs/concepts/#callbacks)\n",
    "\n",
    ":::\n",
    "\n",
    "By default, LangChain.js callbacks are blocking. This means that execution will wait for the callback to either return or timeout before continuing. This is to help ensure that if you are running code in [serverless environments](https://en.wikipedia.org/wiki/Serverless_computing) such as [AWS Lambda](https://aws.amazon.com/pm/lambda/) or [Cloudflare Workers](https://workers.cloudflare.com/), these callbacks always finish before the execution context ends.\n",
    "\n",
    "However, this can add unnecessary latency if you are running in traditional stateful environments. If desired, you can set your callbacks to run in the background to avoid this additional latency by setting the `LANGCHAIN_CALLBACKS_BACKGROUND` environment variable to `\"true\"`. You can then import the global [`awaitAllCallbacks`](https://api.js.langchain.com/functions/langchain_core_callbacks_promises.awaitAllCallbacks.html) method to ensure all callbacks finish if necessary.\n",
    "\n",
    "To illustrate this, we'll create a [custom callback handler](/docs/how_to/custom_callbacks) that takes some time to resolve, and show the timing with and without `LANGCHAIN_CALLBACKS_BACKGROUND` set. Here it is without the variable set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Call finished\n",
      "Elapsed time: 2005ms\n"
     ]
    }
   ],
   "source": [
    "import { RunnableLambda } from \"@langchain/core/runnables\";\n",
    "\n",
    "Deno.env.set(\"LANGCHAIN_CALLBACKS_BACKGROUND\", \"false\");\n",
    "\n",
    "const runnable = RunnableLambda.from(() => \"hello!\");\n",
    "\n",
    "const customHandler = {\n",
    "  handleChainEnd: async () => {\n",
    "    await new Promise((resolve) => setTimeout(resolve, 2000));\n",
    "    console.log(\"Call finished\");\n",
    "  },\n",
    "};\n",
    "\n",
    "const startTime = new Date().getTime();\n",
    "\n",
    "await runnable.invoke({ number: \"2\" }, { callbacks: [customHandler] });\n",
    "\n",
    "console.log(`Elapsed time: ${new Date().getTime() - startTime}ms`);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And here it is with backgrounding on:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initial elapsed time: 0ms\n",
      "Call finished\n",
      "Final elapsed time: 2098ms\n"
     ]
    }
   ],
   "source": [
    "import { awaitAllCallbacks } from \"@langchain/core/callbacks/promises\";\n",
    "\n",
    "Deno.env.set(\"LANGCHAIN_CALLBACKS_BACKGROUND\", \"true\");\n",
    "\n",
    "const startTime = new Date().getTime();\n",
    "\n",
    "await runnable.invoke({ number: \"2\" }, { callbacks: [customHandler] });\n",
    "\n",
    "console.log(`Initial elapsed time: ${new Date().getTime() - startTime}ms`);\n",
    "\n",
    "await awaitAllCallbacks();\n",
    "\n",
    "console.log(`Final elapsed time: ${new Date().getTime() - startTime}ms`);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next steps\n",
    "\n",
    "You've now learned how to run callbacks in the background to reduce latency.\n",
    "\n",
    "Next, check out the other how-to guides in this section, such as [how to create custom callback handlers](/docs/how_to/custom_callbacks)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
